/* Copyright 2018-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
 * applicable law or agreed to in writing, software distributed under the
 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, either express or implied. See the License for the specific
 * language governing permissions and limitations under the License.
 */
package com.demo;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.PageContext;

import com.demo.page.Pages.emptyPage;
import com.demo.page.Pages.homepage;
import com.demo.page.Pages.page404;
import com.github.drinkjava2.gosqlgo.GoSqlGoEnv;
import com.github.drinkjava2.gosqlgo.JavaSrcBuilder;
import com.github.drinkjava2.gosqlgo.QrySrcBuilder;
import com.github.drinkjava2.gosqlgo.ServletTemplate;
import com.github.drinkjava2.gosqlgo.SrcBuilder;
import com.github.drinkjava2.gosqlgo.compile.DynamicCompileEngine;
import com.github.drinkjava2.gosqlgo.util.GsgStrUtils;
import com.github.drinkjava2.gosqlgo.util.Systemout;
import com.github.drinkjava2.jwebbox.WebBox;

/**
 * Change /xxx.htm calls to html pages show
 * 
 * @author Yong Zhu
 * @since 1.0.0
 */
@SuppressWarnings("all")
public class Dispatch {
	public static void dispatch(PageContext pageContext) {
		WebBox box = doDispatch(pageContext);
		box.show(pageContext);
	}

	public static WebBox doDispatch(PageContext pageContext) {
		String uri = GsgStrUtils.substringBefore(((HttpServletRequest) pageContext.getRequest()).getRequestURI(), ".");
		uri = GsgStrUtils.substringAfterLast(uri, "/").toLowerCase();
		if (GsgStrUtils.isEmpty(uri))
			return new homepage();
		if ("qry".equals(uri))
			return buildClassAndRun(pageContext, QrySrcBuilder.instance);
		if ("java".equals(uri))
			return buildClassAndRun(pageContext, JavaSrcBuilder.instance);
		Class<?> pageClass;
		try {
			pageClass = Class.forName("com.demo.page.Pages$" + uri);
			return (WebBox) pageClass.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
			return new page404();
		}
	}

	/**
	 * Dispatch all /qry.htm or /java.htm call to SQL Query
	 */
	public static WebBox buildClassAndRun(PageContext pageContext, SrcBuilder srcBuilder) {
		String sqlOrJavaPiece = pageContext.getRequest().getParameter("$0");
		if (GsgStrUtils.isEmpty(sqlOrJavaPiece))
			return new emptyPage();
		ServletTemplate child = null;

		try {
			Class<?> stored = GoSqlGoEnv.findStoredClass(sqlOrJavaPiece);
			if (stored != null)
				child = (ServletTemplate) stored.newInstance();
			else if (!GoSqlGoEnv.instance.isProduct()) {
				String className = GsgStrUtils.getRandomClassName(10);
				String classSrc = srcBuilder.createSourceCode(className, sqlOrJavaPiece);

				Class<?> childClass = DynamicCompileEngine.instance
						.javaCodeToClass(GoSqlGoEnv.instance.getDeploy() + "." + className, classSrc);
				child = (ServletTemplate) childClass.newInstance();
			} else {
				Systemout.print("Error: in product stage but did not find class stored on server: "
						+ sqlOrJavaPiece.substring(0, 50) + " ...");
				return new emptyPage();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new emptyPage();
		}
		child.setPageContext(pageContext);
		return child.run();
	}

}
